/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
 H       scheduler.h
 H       Application name: tcss422-project2
 H       Programmers names:	Evan Phillips, Lucas Cowell, Tony Butterfield
 H       Date created:	May 19, 2011
 H       Date completed: 
 H       Brief Description: Simulated OS scheduler that handles the context switching of the CPU.
 H
 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/

#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#endif /* SCHEDULER_H_ */

/* FORWARD DEFINITIONS - (aka prototypes) */
struct cpu_str;                 // forward definition of a cpu.
struct process_queue_str;       // forward definition of a process queue
struct process_str;             // forward definition of a process.

/***************************************************************************************************
 *  ADT: Scheduler
 *  Description:  The scheduler is called by the cpu to switch contexts and manage the contents
 *          of the Ready and Blocking queues.
 *
 *          When the running process is blocked or hits the end of its time-slice, the scheduler will
 *          examine the interrupt values and will decide which queue and what state the process
 *          should be in.  Depending on the interrupt code, it will move blocked processes from the
 *          io_device blocked queues to the ready queue.  It will then either change the running
 *          process state back to 'running' and exit, or get the next process from it's ready queue
 *          and set it as the cpu's new running process.
 *
 *          Some issues... we have to process interrupts after the requests so that we can keep track
 *          of the process that's doing the requesting and get it in the right block queue.
 *
 *  Implementation:  Uses a struct to store data to be used by the sim, including the 'Ready Queue'.
 *          it needs references to the cpu, and it needs to be able to access references to each
 *          'blocked queue' owned by the io_devices, and the semaphore object's 'blocked queue'
 *
 ***************************************************************************************************/
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 $ Typedefs
 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
typedef struct scheduler_str
{
        struct process_queue_str* ready_queue;
        struct cpu_str* cpu;

} SchedulerStr;
typedef SchedulerStr* Scheduler;


/*-------------------------------------------------------------------------------------------------
 - Prototypes
 -      Initialize  - create an new scheduler
 -      Terminate   - deallocates memory allocated in Initialize.
 -
 -      Set Ready   - enqueues process into the ready queue, setting state to P_READY.
 -      Get Ready   - dequeues the next process in the ready queue as the cpu's running process and
 -                      set its state to P_RUNNING
 -
 -      Set Blocked - enqueues process into the blocked queue of an io device/semaphore, setting
 -                      state to P_BLOCKED.
 -      Get Blocked - dequeues a process from the blocked queue of an io device/semaphore, setting
 -                      state to P_BLOCKED.
 -
 -      Do Stuff    - determine which interrupts have been thrown and handle them in order of
 -                      priority.
 -                      Note - in this sim, there isn't any way to determine the order
 -      ^
 -       `---   hard stuff here... need to examine the value in the Interrupt Controller and do...
 -              .......... stuff.
 -
 ---------------------------------------------------------------------------------------------------*/
Scheduler   sched_init(struct cpu_str*);
int         sched_free(Scheduler);

int         sched_setReady(Scheduler, struct process_str*);
int         sched_getNextReady(Scheduler);

int         sched_setBlocked(Scheduler, struct process_queue_str*);
int         sched_getBlocked(Scheduler,  struct process_queue_str*);

int         sched_processInterrupts(Scheduler);         // DO STUFF, DAMMIT!

int         sched_timerInterruptHandler(Scheduler);
int         sched_hardwareExceptionHandler(Scheduler);
int         sched_kbdInterruptHandler(Scheduler);
int         sched_dskInterruptHandler(Scheduler);
int         sched_vidInterruptHandler(Scheduler);
int         sched_kbdRequestHandler(Scheduler);
int         sched_dskRequestHandler(Scheduler);
int         sched_vidRequestHandler(Scheduler);
int         sched_semUpRequestHandler(Scheduler);
int         sched_semDwnRequestHandler(Scheduler);

//TODO: handler methods for any other interrupts we need.

